package sanduche.play.generators

import java.util.Properties
import java.io.FileInputStream
import java.io.File
import java.io.PrintWriter

object AndroidGenerator {

  def apply(modules: Seq[SanModule]) {
    val p = new Properties();
    val is = new FileInputStream("dev-source/tasks.properties")
    p.load(is)
    val wsFolder = p.getProperty("android-ws")
    val projectFolder = p.getProperty("android-project")
    val rootPackage = p.getProperty("android-root-package")
    val servicesPackage = rootPackage + ".services"
    val endpointsRoute = s"$wsFolder/$projectFolder/src/${servicesPackage.replace(".", "/")}/EndPoints.java"
    println(s"Generando a: $endpointsRoute")
    val endpointsFileObject = new File(endpointsRoute)
    is.close()

    if (!endpointsFileObject.exists())
      endpointsFileObject.createNewFile();
    val endpointsFile = new PrintWriter(endpointsFileObject);

    endpointsFile.println(s"""package $servicesPackage;
    |import static co.sanduche.util.SanducheUtil.urlInterpolate;    
    |import java.util.List;
    |import com.android.volley.Request.Method;
    |import $rootPackage.models.Models.*;
    |import $rootPackage.vos.*;
    |import $rootPackage.util.EPCallback;
    |import $rootPackage.util.JListRequest;
    |import $rootPackage.util.JObjectRequest;

        
    |public class EndPoints {
    |${modules.map({ m => println("Creado android service " + m.name); toAndroidEndPoint(m) }).mkString("\n")}
    |}
    """.stripMargin)
    endpointsFile.close();

  }

  def toAndroidEndPoint(module: SanModule) = {
    s"""
	|	public static class ${module.name.capitalize}EP{
	|${module.services.map(toVolleyRequest(_, module.prefix)).mkString("\n")}
	|	}
	""".stripMargin
  }

  def toVolleyRequest(service: SanService, prefix: String) = {
    s"""public static void ${service.simpleName}(${((service.urlParams.map(_.declaration) ::: service.maybeBody.map(_.declaration).toList) :+ s"""EPCallback<${service.returnType.rawType.getSimpleName().capitalize ++ service.returnType.maybeGenericType.map("<" ++ _.getSimpleName() ++ ">").getOrElse("")}> handler""").mkString(", ")}){
    EPClient.addRequest(new J${
      if (service.returnType.isIterable) { "List" } else { "Object" }
    }Request${
      if (service.returnType.isIterable) {
        service.returnType.maybeGenericType.map("<" ++ _.getSimpleName().capitalize ++ ">").getOrElse("")
      } else {
        "<" ++ service.returnType.rawType.getSimpleName().capitalize ++ ">"
      }
    }(Method.${service.route.method},urlInterpolate(${(s""""${prefix ++ service.route.value()}"""" :: service.urlParams.map { param => s""""${param.reference}", ${param.reference}""" }) mkString ", "}), ${service.maybeBody.map(_.reference).getOrElse("null")}, ${
      if (service.returnType.isIterable) { service.returnType.maybeGenericType.map(_.getSimpleName()).getOrElse("Void") }
      else { service.returnType.rawType.getSimpleName().capitalize }
    }.class, handler));
    }"""
  }

}